//实时视频 rtc

<template>
  <div class="home">
    <!-- 左侧区域 -->
    <div class="left">
      <div class="left-item1">用户：{{ userId }}</div>
      <div class="left-item2" @click="muteLocalVideo">
        <img src="@/assets/image/camera-on.png" alt="" v-if="!cameraFlag" />
        <img src="@/assets/image/camera-off.png" alt="" v-else />
      </div>
      <div class="left-item2" @click="muteLocalAudio">
        <img src="@/assets/image/microphone.png" alt="" v-if="!bannedFlag" />
        <img src="@/assets/image/mute.png" alt="" v-else />
      </div>
    </div>
    <!-- 中间区域 -->
    <div class="center">
      <!-- 视频窗口 -->
      <div id="local_stream"></div>
      <el-button @click="enterRoom" :disabled="enterFlag">进入房间</el-button>
      <el-button @click="leaveRoom" :disabled="leaveFlag">退出房间</el-button>
      <el-button @click="camerasFun">切换摄像头</el-button>
      <el-button @click="Banned(0)">禁言</el-button>
      <el-button @click="Banned(1)">发言</el-button>
    </div>
    <!-- 右侧区域 -->
    <div class="right">
      <!--远端流-->
      <div
        class="userlist"
        v-for="item in list"
        :class="{ active: activeId == item.id }"
        :key="item.id"
        @click="activeId = item.id"
      >
        <div
          :id="item.id"
          class="distant-stream"
          v-html="item.remoteStream"
        ></div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import LibGenerateTestUserSig from "@/static/js/lib-generate-test-usersig.min.js";

import TRTC from "trtc-js-sdk";
import { onMounted, ref, nextTick } from "vue";
const userId = ref("肖战"); //用户id
// const userId = ref("")//测试
const client = ref(); //客户端服务
const sdkAppId = ref(1400663701); //从腾讯云申请的sdkAppId  number类型
// const sdkAppId = ref();//测试
const secretKey = ref(
  "550569443cee7a8c13af58550f84e9a3e6ac38e380ad6c8c9cd82eae9cf8aa88"
); //从腾讯云申请的密钥
const userSig = ref(""); //用户签名
const roomId = ref(8888); //房间号  number类型
const localStream = ref(); //本地音频流
const remoteStream = ref(""); //远方视频流
const enterFlag = ref(false); // 是否进入房间
const leaveFlag = ref(true); //是否退出房间
const cameras = ref([]); //摄像头
const bannedFlag = ref(false); //是否禁言
const cameraFlag = ref(false); //是否开启摄像头
const list = ref(); //成员列表
const activeId = ref(""); //当前播放的成员id
const isHave = ref(false); //当前列表是否有该成员
//创建链接
const creatClient = () => {
  userId.value = userId.value + parseInt((Math.random() * 100).toString());
  const userSig = genTestUserSig(userId.value);
  //初始化
  client.value = TRTC.createClient({
    mode: "rtc", // rtc: 实时通话模式  live:互动直播模式 （目前就这2中模式）
    userId: userId.value,
    sdkAppId: sdkAppId.value,
    userSig: userSig,
  });
  remoteStreamFun(); //订阅远端流，要放在进入房间之前
  //初始化完成后，进入房间
  joinRoom(roomId.value);
};

//进入房间
const joinRoom = (roomId: any) => {
  client.value
    .join({ roomId: roomId })
    .catch((error: any) => {
      console.error("进房失败" + error);
    })
    .then(() => {
      //创建本地流
      localStreamFun();
      //播放远端流
      playRemoteStream();
      console.log("进房成功！");
    });
};

//创建本地音频流
const localStreamFun = () => {
  localStream.value = TRTC.createStream({
    userId: userId.value,
    audio: true,
    video: true,
  });
  initLocalStreamFun();
};
//初始化本地音视频流
const initLocalStreamFun = () => {
  localStream.value
    .initialize()
    .catch((error: any) => {
      console.log("初始化本地失败" + error);
      //出现异常的情况
      switch (error.name) {
        case "NotFoundError":
          alert("找不到满足请求参数的媒体类型（包括：音频、视频、屏幕分享）!");
          break;
        case "NotAllowedError":
          alert("不授权摄像头/麦克风访问无法进行音视频通话,请确保已授权！");
          break;
        case "NotReadableError":
          alert(
            "暂时无法访问摄像头/麦克风，请确保当前没有其他应用请求访问摄像头/麦克风，并重试！"
          );
          break;
        case "OverconstrainedError":
          console.log("确保 cameraId/microphoneId 传值正确且有效");
          break;
        case "AbortError":
          alert("由于某些未知原因导致设备无法被使用！");
          break;
      }
    })
    .then(() => {
      localStream.value.play("local_stream");
      releaseLocalStreamFun(); //发布本地流
      console.log("初始化本地流成功！");
    });
};
//发布本地流
const releaseLocalStreamFun = () => {
  client.value
    .publish(localStream.value)
    .catch((error: any) => {
      console.log("发布本地流失败" + error);
    })
    .then(() => {
      console.log("发布本地流");
    });
};

//订阅远端音视频流，在join加入房间之前
const remoteStreamFun = () => {
  client.value.on("stream-added", (e: any) => {
    const remoteStream = e.stream;
    console.log("远端流增加" + remoteStream.getId());
    //订阅远端流
    client.value.subscribe(remoteStream);
  });
  // client.value.on("stream-subscribed", (e: any) => {
  //   const remoteStream = e.stream;
  //   console.log("远端流订阅成功：" + remoteStream.getId());
  //   //播放远端流
  //   remoteStream.play("local_stream");
  // });
};

// //播放音频流
// const playAudio = () => {
//   localStream.value
//     .initialize()
//     .catch((error: any) => {
//       console.error("初始化本地流失败" + error);
//     })
//     .then(() => {
//       console.log("初始化本地流成功");
//       localStream.value.play("local_stream");
//       playRemoteStream();
//     });
// };

//订阅远端流成功时播放远端流
const playRemoteStream = async () => {
  client.value.on("stream-subscribed", (event: any) => {
    const remoteStream = event.stream;

    //创建远端远端流标签，所以动态创建使用v-html
    remoteStream.value = `<div id="${
      "remote_stream-" + remoteStream.getId()
    }"  style="width:100%;height:100%"></div>`;
    console.log("远端流订阅成功,播放远端流" + remoteStream.getId());
    console.log(remoteStream.value);
    if (isHave.value) {
      list.value.push({
        id: remoteStream.getId(),
        userId: remoteStream.getUserId(),
        remoteStream: remoteStream.value,
        origin: remoteStream,
      });
    } else {
      list.value.splice(
        list.value.findIndex((v: any) => v.userId === remoteStream.getUserId()),
        1,
        {
          id: remoteStream.getId(),
          userId: remoteStream.getUserId(),
          remoteStream: remoteStream.value,
          origin: remoteStream,
        }
      );
    }
    debugger;
    //操作dom了，避免创建的标签找不到，使用nextTick()
    nextTick(() => {
      //播放远端流
      remoteStream.play("remote_stream-" + remoteStream.getId());
    });
  });
};
//退出音频通话
const leaveRoom = () => {
  client.value
    .leave()
    .then(() => {
      console.log("退房成功！");
      //停止本地流，关闭本地流内部的音视频播放器
      localStream.value.stop();
      localStream.value.close();
      localStream.value = null;
      //初始化状态置为空null
      client.value = null;
      enterFlag.value = false;
      leaveFlag.value = true;
    })
    .catch((error: any) => {
      console.error("退房失败" + error);
      //错误恢复，需要刷新页面
    });
};
//进入房间
const enterRoom = () => {
  creatClient();
  enterFlag.value = true;
  leaveFlag.value = false;
};

// 获取用户签名--前端测试用，后面要从后端获取
const genTestUserSig = (userID: any) => {
  const SDKAPPID = sdkAppId.value; //用户id
  /**
   * 签名过期的时间 ，不建议设置过短
   * 时间单位： 秒 s
   * 默认时间： 7*24*60*60 = 604800   7天
   */
  const EXPIRETIME = 604800; //签名过期时间
  const SECRETKEY = secretKey.value; //密钥

  if (SDKAPPID == null || SECRETKEY == "") {
    alert("请先配置好您的账号信息： SDKAPPID 及 SECRETKEY");
    return false;
  }
  const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME);
  const userSig = generator.genTestUserSig(userID);
  return userSig;
};

//切换摄像头
const camerasFun = () => {
  TRTC.getCameras().then((devices: any) => {
    cameras.value = devices;
    console.log(cameras.value);

    //获取摄像头列表
    devices.forEach((dev: any) => {
      console.log("camera label: " + dev.label + " deviceId: " + dev.deviceId);
    });
  });
  let cameraId = cameras.value[0];
  localStream.value.switchDevice("video", cameraId.deviceId).then(() => {
    console.log("摄像头切换成功");
  });
};
//禁止音频通知
const Banned = (val: number) => {
  let param = val == 1 ? "unmute-audio" : "mute-audio"; //unmute-audio：开启音频   mute-audio：关闭音频
  client.value.on(param, (event: any) => {
    bannedFlag.value = true;
    const userId = event.userId;
    console.log(userId);
  });
};

//是否开启摄像头
const muteLocalVideo = () => {
  if (cameraFlag.value) {
    cameraFlag.value = false;
    localStream.value.unmuteVideo(); //开启本地摄像头
  } else {
    cameraFlag.value = true;
    localStream.value.muteVideo(); //关闭本地摄像头
  }
};

//是否静音
const muteLocalAudio = () => {
  if (bannedFlag.value) {
    bannedFlag.value = false;
    localStream.value.unmuteAudio();
  } else {
    bannedFlag.value = true;
    localStream.value.muteAudio();
  }
};

onMounted(() => {});
</script>

<style lang="scss" scoped>
.home {
  height: 100%;
  flex: 1;
  display: flex;
  padding: 20px;
  .left,
  .right {
    flex: 0.4;
    padding: 10px;
    background-color: #fff;
  }
  .left {
    display: flex;
    .left-item1 {
      flex: 1;
    }
    .left-item2 {
      flex: 0.5;
      img {
        width: 30px;
        height: 30px;
      }
    }
  }
  .center {
    flex: 1;
    padding: 0 15px;
    #local_stream {
      min-height: 500px;
      border: 1px solid red;
    }
  }
}
</style>
